// Dwarf.Unmanaged.Serial.cpp : Defines the entry point for the console application.
//

#include "Dwarf.Unmanaged.Serial.h"

using namespace std;

// The settings for this dwarf.
static Settings* settings;

//Init & fill neigbourhood array
static inline void constructNeighborhood(Solver *ugsolver)
{       
    //Init map
    Neighborhood *neighborhood = new Neighborhood();
    for (unsigned int i = 0; i < ugsolver->numVertex; i ++)    
    {
        neighborhood->insert(make_pair( i, new SetOfVertex() ));
    }

    //Insert verteces into map
    for (unsigned int j = 0; j < ugsolver->numTriangles; j ++)
    {
        ((SetOfVertex*)neighborhood->find(ugsolver->triangles[0][j])->second)->insert(ugsolver->triangles[1][j]);
        ((SetOfVertex*)neighborhood->find(ugsolver->triangles[0][j])->second)->insert(ugsolver->triangles[2][j]);

        ((SetOfVertex*)neighborhood->find(ugsolver->triangles[1][j])->second)->insert(ugsolver->triangles[0][j]);
        ((SetOfVertex*)neighborhood->find(ugsolver->triangles[1][j])->second)->insert(ugsolver->triangles[2][j]);

        ((SetOfVertex*)neighborhood->find(ugsolver->triangles[2][j])->second)->insert(ugsolver->triangles[0][j]);
        ((SetOfVertex*)neighborhood->find(ugsolver->triangles[2][j])->second)->insert(ugsolver->triangles[1][j]);
    }

    //Copy from map to array
    for (unsigned int i = 0; i < ugsolver->numVertex; i ++)
    {
        SetOfVertex *vSet = (SetOfVertex*)neighborhood->find(i)->second;
        ugsolver->numNeighbors[i] = (int)vSet->size();
        ugsolver->neighborhood[i] = new unsigned int[ugsolver->numNeighbors[i]];

        int j = 0;
        for( SetOfVertex::iterator iter = vSet->begin(); iter != vSet->end(); iter++ ) 
        {		
            ugsolver->neighborhood[i][j ++] = *iter;
	    }
    }

    //Dispose map
    for( Neighborhood::iterator iter = neighborhood->begin(); iter != neighborhood->end(); iter++ ) 
    {		
	    delete iter->second;
    }
}

// Get settings from the command line.
static int getSettings(int argc, char** argv, Solver *ugsolver) 
{
    settings = new Settings();
    if (settings->init(argc,argv,ugsolver))         //Parse all arguments for dwarf.
    {            
        delete settings;
        return -1;
    }
    
    constructNeighborhood(ugsolver);                //Fill neighborhood array

    return 0;
}

// Point of the program start.
void main(int argc, char** argv)
{   
    Solver* ugsolver = new Solver();        

    if (getSettings(argc, argv, ugsolver))     // Get settings from the command line.
    {
        delete ugsolver;
        exit(-1);
    }

    settings->start();                          // Start new time count.
    ugsolver->solve();                         // Solve the current problem.
    settings->finish(ugsolver);                // Stop the time count and write results.

    //Dispose objects.
    delete settings;
    delete ugsolver;
}